﻿using System;
using System.Collections.Generic;
using System.Text;
using WsProtocol.IEC62056.DataTypeClass;
using Comm.PublicClass;


namespace WsProtocol.IEC62056.CosemACSE
{   /// <summary>
    /// 62056 实现抄读服务原语的所有类
    /// </summary> 

    public class GetNormal
    {
        public static string Request(CosemObject OI,ref string errorinfo)
        {
            try
            {
                return ADWithSel.GetFormatValue(OI,ref errorinfo);
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }

        public static int Response(ref string frameData, CosemObject OI, ref string errorinfo)
        {
            int iResult = 0;
            if (string.IsNullOrEmpty(frameData))
            {
                return iResult;
            }
            try
            {
                if (OI == null)
                    OI = new CosemObject();

                string errorflag = frameData.Substring(0, 2);
                if (MyConvert.getInt32(errorflag) == (int)GetResult.AccessResult)
                {
                    iResult = 0;
                    errorflag = Enum.GetName(typeof(DAR), (DAR)Convert.ToInt32(frameData.Substring(2, 2), 16));
                    errorflag = errorflag;
                    OI.result = MyConvert.HexToDec(frameData.Substring(2, 2)) + ":" + errorflag;
                    if (errorflag == null)
                        OI.result += "协议中未规定此错误号对应的错误信息" ; 
                    frameData = frameData.Remove(0, 4); //去掉有错标志及错误标志　
                }
                else if (MyConvert.getInt32(errorflag) == (int)GetResult.data)
                {
                    frameData = frameData.Remove(0, 2); //去掉数据标志　01
                    OI.result = "0";

                    if (OI.DataNode == null)                   
                        OI.AddNode(new ElementData());  //创建一个新数据节点
                  
                    iResult = Data.AnalizeData(ref frameData, OI.DataNode, ref errorinfo);
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }

    }
    //初步代码处理完成
    public class GetWithList : GetNormal
    {
        public static string Request(List<CosemObject> OIList, ref string errorinfo)
        {
            try
            {
                string FormatValue = string.Empty;
                int eleNum = OIList.Count;

                foreach (CosemObject OI in OIList)
                {
                    FormatValue = FormatValue + GetNormal.Request(OI,ref errorinfo);
                }
                
                return BERiLen.GetFormatValue(eleNum) + FormatValue;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }

        public static int Response(ref string frameData, List<CosemObject> OIList, ref string errorinfo)
        {
            int iResult = 0;
            if (string.IsNullOrEmpty(frameData))
            {
                return iResult;
            }
            try
            {               
                int eleNum = BERiLen.AnalizeData(ref frameData, ref errorinfo);
                if (eleNum < 0)
                {
                    return -1;
                }

                CosemObject OI = null;
                CosemObject lastOI = OIList[OIList.Count - 1];
                for (int i = 0; i < eleNum; i++)
                {
                    //Application.DoEvents();
                    if (i >= OIList.Count)
                    {
                        OI = new CosemObject();//hxh 对象不克隆,只生成 (CosemObject)lastOI.DeepClone(); //如果数据格式不够，按最后一个OI克隆一个
                        OIList.Add(OI);
                    }
                    else
                        OI = OIList[i];

                    iResult = GetNormal.Response(ref frameData, OI, ref errorinfo);

                    if (iResult < 0) break;
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }

    }

    //初步代码处理完成，解析的数据处理暂不清楚
    public class GetNext
    {
        public static string Request(double frameseq, ref string errorinfo)
        {
            try
            {
                return MyConvert.DecToHex(frameseq.ToString(), 4 * 2); //Unsigned32 4字节
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }

        public static int Response(ref string frameData, CosemObject OI, ref long frameseq, ref bool finished,ref string RawData, ref string errorinfo)
        {
            int iResult = -1;
            if (string.IsNullOrEmpty(frameData))
            {
                return iResult;
            }
            try
            {
                finished = Convert.ToUInt32(frameData.Substring(0, 2),16) >= 1; //末帧标志 BOOLEAN
                long iframeseq = Convert.ToInt64(frameData.Substring(2, 8), 16);//帧序号unsigned32               
                frameData = frameData.Remove(0, 10);

                string errorflag = frameData.Substring(0, 2);//响应类型
                frameData = frameData.Remove(0, 2);

                if (MyConvert.getInt32(errorflag) == (int)GetResult.AccessResult) //错误信息,错误时不更新帧序号
                {
                    iResult = 0;
                    errorinfo = Enum.GetName(typeof(DAR), (DAR)Convert.ToInt32(frameData.Substring(2, 2), 16));
                    //errorinfo = errorinfo;
                    OI.result = MyConvert.HexToDec(frameData.Substring(2, 2)) + ":" + errorinfo;
                    RawData = string.Empty;                   
                }
                else
                {
                    iResult = 0;
                    OI.result = "0";
                    frameseq = iframeseq; //更新帧序号
                    RawData = octString.AnalizeDataSpecial(ref frameData, ref errorinfo);
                   // OI.DataNode.FrameValue = framestr;
                    //iResult =Data.AnalizeData(ref framestr, OI.DataNode, ref errorflag);//要不要解析到时再定                   
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;
        }

    }


    //初步代码处理完成
    public class ACSE_Get
    {
        static string m_piid = "81";

        public static string Request(List<CosemObject> OIList, string rwtype, long frameseq, ref string errorinfo)
        {
            try
            {
                string FormatValue = string.Empty;

                GetRRMode getMode = (GetRRMode)Enum.Parse(typeof(GetRRMode), rwtype);

                switch (getMode)
                {
                    case GetRRMode.GetNormal:
                        FormatValue = GetNormal.Request(OIList[0],ref errorinfo);
                        break;
                    case GetRRMode.GetWithList:
                        FormatValue = GetWithList.Request(OIList, ref errorinfo);
                        break;                 
                    case GetRRMode.GetNext:
                        FormatValue = GetNext.Request(frameseq, ref errorinfo);
                        break;
                 
                }
                //return MyConvert.DecToHex(((int)ClientApduSel.GETRequest).ToString(), 2) + MyConvert.DecToHex(((int)getMode).ToString(), 2) + m_piid + FormatValue;
                return FormatValue;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }
        public static int Response(ref string frameData, List<CosemObject> m_OIList, ref long frameseq, ref bool finished, ref string RawData, ref string errorinfo)
        {
            int iResult = 0;
            try
            {

                if (string.IsNullOrEmpty(frameData)) return -1;

                GetRRMode getMode = (GetRRMode)Enum.Parse(typeof(GetRRMode), frameData.Substring(0, 2));
                string piid = frameData.Substring(2, 2);

                frameData = frameData.Substring(4); //去掉前面的回应类标志、PIID

                switch (getMode)
                {
                    case GetRRMode.GetNormal:
                        //只一个OAD
                        iResult = GetNormal.Response(ref frameData, m_OIList[0], ref  errorinfo);
                        break;
                    case GetRRMode.GetWithList:
                        //包含多个OAD
                        iResult = GetWithList.Response(ref frameData, m_OIList, ref  errorinfo);
                        break;                   
                    case GetRRMode.GetNext:
                        iResult = GetNext.Response(ref frameData, m_OIList[0], ref frameseq, ref finished,ref RawData, ref  errorinfo);
                        break;
                   
                }
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
            }
            return iResult;
        }
    }

   


}
